import * as Taro from '@tarojs/taro'
import { createContext, ReactNode, useContext, useReducer } from 'react'
import { AuthService } from '../services/auth'

interface User {
  id: number
  nickname: string
  avatar: string
  phone: string
  level: string
  points: number
  openid?: string
  unionid?: string
}

interface AuthState {
  isLoggedIn: boolean
  user: User | null
  isLoading: boolean
}

type AuthAction =
  | { type: 'LOGIN_START' }
  | { type: 'LOGIN_SUCCESS'; payload: User }
  | { type: 'LOGIN_FAILURE' }
  | { type: 'LOGOUT' }

const authReducer = (state: AuthState, action: AuthAction): AuthState => {
  switch (action.type) {
    case 'LOGIN_START':
      return {
        ...state,
        isLoading: true,
      }
    case 'LOGIN_SUCCESS':
      return {
        isLoggedIn: true,
        user: action.payload,
        isLoading: false,
      }
    case 'LOGIN_FAILURE':
      return {
        ...state,
        isLoading: false,
      }
    case 'LOGOUT':
      return {
        isLoggedIn: false,
        user: null,
        isLoading: false,
      }
    default:
      return state
  }
}

interface AuthContextType {
  state: AuthState
  login: (user: User) => void
  logout: () => void
  wechatLogin: () => Promise<void>
  wechatProfileLogin: () => Promise<void>
}

const AuthContext = createContext<AuthContextType | undefined>(undefined)

export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [state, dispatch] = useReducer(authReducer, {
    isLoggedIn: false,
    user: null,
    isLoading: false,
  })

  const loginSuccess = (user: User) => {
    dispatch({ type: 'LOGIN_SUCCESS', payload: user })
    // 保存登录状态到本地
    Taro.setStorageSync('userInfo', user)
    Taro.setStorageSync('isLoggedIn', true)
  }

  const logout = () => {
    dispatch({ type: 'LOGOUT' })
    // 清除本地存储
    Taro.removeStorageSync('userInfo')
    Taro.removeStorageSync('isLoggedIn')
  }

  // 微信登录方法（使用传统后端接口）
  const wechatLogin = async (): Promise<void> => {
    try {
      dispatch({ type: 'LOGIN_START' })

      const response = await AuthService.wechatLogin()

      const user: User = {
        id: response.userId,
        nickname: response.nickname,
        avatar: response.avatarUrl,
        phone: '',
        level: '普通会员',
        points: 0,
        openid: response.openid,
        unionid: response.unionid,
      }

      // 记录 user 信息
      loginSuccess(user)

      Taro.showToast({
        title: '登录成功',
        icon: 'success',
        duration: 2000,
      })
    } catch (error) {
      dispatch({ type: 'LOGIN_FAILURE' })

      console.error('微信登录失败:', error)
      Taro.showToast({
        title: error.message || '登录失败，请重试',
        icon: 'error',
        duration: 2000,
      })
    }
  }

  const wechatProfileLogin = async (): Promise<void> => {
    try {
      dispatch({ type: 'LOGIN_START' })

      // 获取用户信息授权 - 注意：这个方法必须在用户点击事件中直接调用
      const userInfoRes = await Taro.getUserProfile({
        desc: '用于完善用户资料', // 必须填写获取用户信息的用途
      })

      const response = await AuthService.wechatProfileLogin({
        encryptedData: userInfoRes.encryptedData,
        iv: userInfoRes.iv,
      })

      const user: User = {
        id: response.userId,
        nickname: response.nickname,
        avatar: response.avatarUrl,
        phone: '',
        level: '普通会员',
        points: 0,
        openid: response.openid,
        unionid: response.unionid,
      }

      // 记录 user 信息
      loginSuccess(user)

      Taro.showToast({
        title: '登录成功',
        icon: 'success',
        duration: 2000,
      })
    } catch (error) {
      dispatch({ type: 'LOGIN_FAILURE' })

      console.error('微信显式登录失败:', error)

      // 特别处理 getUserProfile 权限错误
      if (error.message && error.message.includes('getUserProfile')) {
        Taro.showToast({
          title: '请点击按钮进行授权登录',
          icon: 'none',
          duration: 3000,
        })
      } else {
        Taro.showToast({
          title: error.message || '登录失败，请重试',
          icon: 'error',
          duration: 2000,
        })
      }
    }
  }

  return (
    <AuthContext.Provider
      value={{
        state,
        login: loginSuccess,
        logout,
        wechatLogin,
        wechatProfileLogin,
      }}>
      {children}
    </AuthContext.Provider>
  )
}

export const useAuth = () => {
  const context = useContext(AuthContext)
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider')
  }
  return context
}
